﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Infrastructure;
using Infrastructure.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;


namespace Xierun.Mvc.Controllers
{
    [AllowAnonymous]
    public class TestController : Controller
    {

        private ApplicationPartManager _applicationPartManager;

        public TestController(ApplicationPartManager applicationPartManager)
        {
            _applicationPartManager = applicationPartManager;
            
        }
    

        public IEnumerable<dynamic> List()
        {
            var controllerFeature = new ControllerFeature();
            _applicationPartManager.PopulateFeature(controllerFeature);
            var data = controllerFeature.Controllers.Select(x => new
            {
                AreaName = GetArea(x.FullName),
                ControllerName = x.Name.Replace("Controller", ""),
                Namespace = x.Namespace,
                Controller = x.FullName,
                ModuleName = x.Module.Name,
                Actions = x.DeclaredMethods.Where(m => m.IsPublic && !m.IsDefined(typeof(NonActionAttribute))).Select(y => new
                {
                    Name = y.Name,
                    ParameterCount = y.GetParameters().Length,
                    Parameters = y.GetParameters()
                        .Select(z => new
                        {
                            z.Name,
                            z.ParameterType.FullName,
                            z.Position,
                            Attrs = z.CustomAttributes.Select(m => new
                            {
                                FullName = m.AttributeType.FullName,
                            })
                        })
                }),
            });
            return data;
        }

        private String GetArea(string fullname)
        {
            string result = "";
            if (fullname.Contains("Areas"))
            {
                result = fullname?.Substring(fullname.IndexOf("Areas", StringComparison.Ordinal)).Replace("Areas.", "");
                result= result.Substring(0,result.IndexOf('.'));
            }
            return result;
        }

        public IActionResult Index(string name)
        {
            var controllerFeature = new ControllerFeature();
            _applicationPartManager.PopulateFeature(controllerFeature);
            var data = controllerFeature.Controllers.Select(x => new ControllerData
            {
                AreaName= GetArea(x.FullName),
                ControllerName = x.Name.Replace("Controller", ""),
                Namespace = x.Namespace,               
                Controller = x.FullName,
                ModuleName = x.Module.Name,
                Actions = x.DeclaredMethods.Where(m => m.IsPublic && !m.IsDefined(typeof(NonActionAttribute))).Select(y => new ActionData
                {                   
                    Name = y.Name,
                    ParameterCount = y.GetParameters().Length,
                    HttpMethods = string.Join(",", y.CustomAttributes.Where(h => h.AttributeType.Name.StartsWith("Http")).Select(m => m.AttributeType.Name.Replace("Http", "").Replace("Attribute", "")).ToArray()) ,
                    //HttpMethods =string.Join(',', y.CustomAttributes.Select(y => new{Name=y.AttributeType.Name}).ToArray()) ,
                    Parameters = y.GetParameters()
                        .Select(z => new
                        {
                            z.Name,
                            z.ParameterType.FullName,
                            z.Position,
                            Attrs = z.CustomAttributes.Select(m => new
                            {
                                FullName = m.AttributeType.FullName,
                            })
                        })
                }),
            });
            //ViewBag.Data = data;
            return View(data);
        }
    }
}
